home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / misc / volume18 / notation / part03 < prev    next >
Encoding:
Internet Message Format  |  1991-04-13  |  33.9 KB

  1. From: hthomas@irisa.fr (Henry Thomas)
  2. Newsgroups: comp.sources.misc
  3. Subject: v18i014:  notation - Chess text converter, Part03/03
  4. Message-ID: <1991Apr12.032957.3667@sparky.IMD.Sterling.COM>
  5. Date: 12 Apr 91 03:29:57 GMT
  6. Approved: kent@sparky.imd.sterling.com
  7. X-Checksum-Snefru: ff5d41b2 1de730ab 399df4a7 de19c66e
  8.  
  9. Submitted-by: Henry Thomas <hthomas@irisa.fr>
  10. Posting-number: Volume 18, Issue 14
  11. Archive-name: notation/part03
  12.  
  13. #! /bin/sh
  14. # This is a shell archive.  Remove anything before this line, then unpack
  15. # it by saving it into a file and typing "sh file".  To overwrite existing
  16. # files, type "sh file -c".  You can also feed this as standard input via
  17. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  18. # will see the following message at the end:
  19. #        "End of archive 3 (of 3)."
  20. # Contents:  notation.c
  21. # Wrapped by hthomas@illico on Thu Apr 11 14:44:55 1991
  22. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  23. if test -f 'notation.c' -a "${1}" != "-c" ; then 
  24.   echo shar: Will not clobber existing file \"'notation.c'\"
  25. else
  26. echo shar: Extracting \"'notation.c'\" \(31006 characters\)
  27. sed "s/^X//" >'notation.c' <<'END_OF_FILE'
  28. X/* Programme d'analyse de notation echiquienne
  29. X   Copyright (C) 1990 Henry Thomas
  30. X   Nom: notation.c
  31. X   Auteur: Henry Thomas
  32. X   Date: 27/11/90
  33. X   */
  34. X/* @(#)notation.c    2.1 4/11/91 (C) Henry Thomas */
  35. X/*
  36. XThis file is part of NOTATION program.
  37. X
  38. XNOTATION is free software; you can redistribute it and/or modify
  39. Xit under the terms of the GNU General Public License as published by
  40. Xthe Free Software Foundation; either version 1, or (at your option)
  41. Xany later version.
  42. X
  43. XNOTATION is distributed in the hope that it will be useful,
  44. Xbut WITHOUT ANY WARRANTY; without even the implied warranty of
  45. XMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  46. XGNU General Public License for more details.
  47. X
  48. XYou should have received a copy of the GNU General Public License
  49. Xalong with NOTATION; see the file COPYING.  If not, write to
  50. Xthe Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  51. X
  52. X/* --------------------- data part ---------------------- */
  53. X
  54. X/* les tableaux suivants sont les tables de transcription de notation
  55. X   selon les langages
  56. X   */
  57. X#include <stdio.h>
  58. X#include <string.h>
  59. X#include <ctype.h>
  60. X
  61. X#include "chesstype.h"
  62. X#include "drivers.h"
  63. X#include "notation.h"
  64. X#include "lexer.h"
  65. X
  66. Xextern void close_files();
  67. X
  68. X
  69. Xchar * version_string =
  70. X  "@(#)notation.c    2.1 (C) Henry Thomas\tVersion 2.1\tDated 4/11/91";
  71. X
  72. Xstatic char * keywords[]= {
  73. X  "@startplay" , "@clearboard" , "@showboard" ,
  74. X  "@whitesmove", "@blacksmove", "@configwhite", "@configblack" ,
  75. X  "@default" , "@special", "@null"
  76. X  };
  77. X
  78. Xint configuring = FALSE ;
  79. Xint configside = 0 ;
  80. X
  81. X
  82. Xstatic char * t_language[] = {
  83. X  "french", "english", "italian", "spanish", "german", "dutch" };
  84. X
  85. Xstatic int in_language = DEFAULT_INPUT_LANGUAGE ;
  86. Xstatic int out_language = DEFAULT_OUTPUT_LANGUAGE ;
  87. X
  88. Xstatic char c_french[]  = { '@' ,'R' , 'D' , 'T' , 'F' , 'C' , 'P' } ;
  89. Xstatic char c_english[] = { '@' ,'K' , 'Q' , 'R' , 'B' , 'N' , 'P' } ;
  90. Xstatic char c_italian[] = { '@' ,'R' , 'D' , 'T' , 'A' , 'C' , 'P' } ;
  91. Xstatic char c_spanish[] = { '@' ,'R' , 'D' , 'T' , 'A' , 'C' , 'P' } ;
  92. Xstatic char c_german[]  = { '@' ,'K' , 'D' , 'T' , 'L' , 'S' , 'B' } ;
  93. Xstatic char c_dutch[]   = { '@' ,'K' , 'D' , 'T' , 'L' , 'P' , 'O' } ;
  94. Xstatic char c_russian[] = { '@' ,'K' , 'F' , 'D' , 'C' , 'K' , 'P' } ;
  95. X
  96. X
  97. X/* translation tables */
  98. Xchar *in_table;
  99. X
  100. Xchar *  c_roque[] = { "O-O" , "O-O-O" , "o-o" , "o-o-o" , "0-0" , "0-0-0" };
  101. X
  102. X/* various notations for en passant */
  103. X#define N_EP 2
  104. Xchar * c_en_passant[] = { "ep" , "e.p." } ;
  105. X
  106. X
  107. X/* notation for catch */
  108. Xchar c_prise ='x';
  109. X
  110. X/* various comments */
  111. Xchar * c_comments[] = { "+" , "++" , 
  112. X              "?" , "??", "!", "!!", "!?", "?!",
  113. X              "mate", "draw" };
  114. X
  115. X/* movement tables */
  116. X/* move only */
  117. X/* white pawn, move */
  118. X#define NB_M_PAWN_MOVE_WD 2
  119. Xstatic int m_pawn_move_wd [][2] = {
  120. X  { 1, 0}, {2, 0}
  121. X};
  122. X
  123. X/* black pawn, move */
  124. X#define NB_M_PAWN_MOVE_BD 2
  125. Xstatic int m_pawn_move_bd [][2] = {
  126. X  {-1, 0}, {-2, 0}
  127. X};
  128. X
  129. X/* TRICK = we have added the catching move at the end of
  130. X   the non catching ones; so in check_depl, we try first 
  131. X   the non catching one and then the catching one.
  132. X   So, even if catching (x) is non indicated in the input, 
  133. X   we succeed in guessing the move
  134. X   */
  135. X/* white pawn, move */
  136. X/*#define NB_M_PAWN_WD 2*/
  137. X#define NB_M_PAWN_WD 4
  138. Xstatic int m_pawn_wd [][2] = {
  139. X  { 1, 0}, {2, 0},
  140. X/* catch... */
  141. X  { 1, 1}, { 1,-1}
  142. X};
  143. X
  144. X/* white pawn, catch */
  145. X#define NB_M_PAWN_WX 2
  146. Xstatic int m_pawn_wx [][2] = {
  147. X  { 1, 1}, { 1,-1}
  148. X};
  149. X
  150. X/* black pawn, move */
  151. X/*#define NB_M_PAWN_BD 2*/
  152. X#define NB_M_PAWN_BD 4
  153. Xstatic int m_pawn_bd [][2] = {
  154. X  {-1, 0}, {-2, 0},
  155. X/* catch... */
  156. X  {-1, 1}, {-1,-1} 
  157. X};
  158. X
  159. X/* black pawn, catch */
  160. X#define NB_M_PAWN_BX 2
  161. Xstatic int m_pawn_bx [][2] = {
  162. X  {-1, 1}, {-1,-1} 
  163. X};
  164. X
  165. X
  166. X#define NB_M_KNIGHT  8
  167. Xstatic int m_knight[][2] = { 
  168. X  { 2, 1}, { 2,-1}, {-2, 1}, {-2,-1},
  169. X  { 1, 2}, { 1,-2}, {-1, 2}, {-1,-2}
  170. X};
  171. X
  172. X#define NB_M_BISHOP 28
  173. Xstatic int m_bishop[][2] = {
  174. X  { 7, 7},  {6, 6}, { 5, 5}, { 4, 4}, { 3, 3}, { 2, 2}, { 1, 1},
  175. X  { 7,-7}, { 6,-6}, { 5,-5}, { 4,-4}, { 3,-3}, { 2,-2}, { 1,-1},
  176. X  {-7,-7}, {-6,-6}, {-5,-5}, {-4,-4}, {-3,-3}, {-2,-2}, {-1,-1},
  177. X  {-7, 7}, {-6, 6}, {-5, 5}, {-4, 4}, {-3, 3}, {-2, 2}, {-1, 1}
  178. X};
  179. X
  180. X#define NB_M_ROOK 28
  181. Xstatic int m_rook[][2] = {
  182. X  { 7, 0}, { 6, 0}, { 5, 0}, { 4, 0}, { 3, 0}, { 2, 0}, { 1, 0},
  183. X  {-7, 0}, {-6, 0}, {-5, 0}, {-4, 0}, {-3, 0}, {-2, 0}, {-1, 0},
  184. X  { 0, 7}, { 0, 6}, { 0, 5}, { 0, 4}, { 0, 3}, { 0, 2}, { 0, 1},
  185. X  { 0,-7}, { 0,-6}, { 0,-5}, { 0,-4}, { 0,-3}, { 0,-2}, { 0,-1}
  186. X};
  187. X
  188. X#define NB_M_QUEEN 56
  189. Xstatic int m_queen[][2] = {
  190. X  { 7, 7},  {6, 6}, { 5, 5}, { 4, 4}, { 3, 3}, { 2, 2}, { 1, 1},
  191. X  { 7,-7}, { 6,-6}, { 5,-5}, { 4,-4}, { 3,-3}, { 2,-2}, { 1,-1},
  192. X  {-7,-7}, {-6,-6}, {-5,-5}, {-4,-4}, {-3,-3}, {-2,-2}, {-1,-1},
  193. X  {-7, 7}, {-6, 6}, {-5, 5}, {-4, 4}, {-3, 3}, {-2, 2}, {-1, 1},
  194. X  { 7, 0}, { 6, 0}, { 5, 0}, { 4, 0}, { 3, 0}, { 2, 0}, { 1, 0},
  195. X  {-7, 0}, {-6, 0}, {-5, 0}, {-4, 0}, {-3, 0}, {-2, 0}, {-1, 0},
  196. X  { 0, 7}, { 0, 6}, { 0, 5}, { 0, 4}, { 0, 3}, { 0, 2}, { 0, 1},
  197. X  { 0,-7}, { 0,-6}, { 0,-5}, { 0,-4}, { 0,-3}, { 0,-2}, { 0,-1}
  198. X};
  199. X
  200. X#define NB_M_KING 8
  201. Xstatic int m_king[][2] = {
  202. X  { 1, 1}, { 1, 0}, { 1,-1},
  203. X  {-1, 1}, {-1, 0}, {-1,-1},
  204. X  { 0, 1}, { 0, -1}
  205. X};
  206. X
  207. X
  208. X/* I/O */
  209. XFILE * infile ;
  210. XFILE * fhelp;
  211. X
  212. Xstatic char * t_output[] = 
  213. X{ "ascii", "postscript", "tex", "roff", "xchess", "gnu" };
  214. X
  215. X
  216. X/* ---------- automata definitions --------- */
  217. X/* table for syntaxic analysis of move */
  218. X
  219. X#define FINAL    10
  220. X#define TML     FINAL   /* terminal state */
  221. X#define NBETAT     11
  222. X#define NBCLAS     8
  223. X
  224. X/* successor of state */
  225. Xstatic int transit[NBETAT][NBCLAS] = { 
  226. X/*   P a-h 1-8   -   x   =  \0   ? */ 
  227. X/*(  0   1   2   3   4   5   6   7)*/
  228. X  {  1,  2, -1, -1, -1, -1, -1, -1 }, /* etat  0 */
  229. X  { -1,  2, -1, -1,  4, -1, -1, -1 }, /* etat  1 */
  230. X  { -1,  6,  3,  4,  4,  8,TML,TML }, /* etat  2 */
  231. X  { -1,  6, -1,  4,  4,  8,TML,TML }, /* etat  3 */
  232. X  {  5,  6, -1, -1, -1, -1, -1, -1 }, /* etat  4 */
  233. X  { -1,  6, -1, -1, -1, -1, -1, -1 }, /* etat  5 */
  234. X  { -1, -1,  7, -1, -1, -1, -1, -1 }, /* etat  6 */
  235. X  { -1, -1, -1, -1, -1,  8,TML,TML }, /* etat  7 */
  236. X  {  9, -1, -1, -1, -1, -1, -1, -1 }, /* etat  8 */
  237. X  { -1, -1, -1, -1, -1, -1,TML,TML }, /* etat  9 */
  238. X  { -1, -1, -1, -1, -1, -1, -1, -1 }  /* etat 10 == terminal */
  239. X};
  240. X
  241. X/* actions to do */
  242. Xstatic int action[NBETAT][NBCLAS] = {
  243. X/*   P a-h 1-8   -   x   =  \0   ? */ 
  244. X  {  1,  2, -1, -1, -1, -1, -1, -1 }, /* etat  0 */
  245. X  { -1,  2, -1, -1, 10, -1, -1, -1 }, /* etat  1 */
  246. X  { -1, 13,  3,  4,  5, 14,  6,  7 }, /* etat  2 */
  247. X  { -1, 13, -1,  4,  5, 14,  6,  7 }, /* etat  3 */
  248. X  {  1,  2, -1, -1, -1, -1, -1, -1 }, /* etat  4 */
  249. X  { -1,  2, -1, -1, -1, -1, -1, -1 }, /* etat  5 */
  250. X  { -1, -1,  3, -1, -1, -1, -1, -1 }, /* etat  6 */
  251. X  { -1, -1, -1, -1, -1, 14,  8,  9 }, /* etat  7 */
  252. X  { 15, -1, -1, -1, -1, -1, -1, -1 }, /* etat  8 */
  253. X  { -1, -1, -1, -1, -1, -1, 17, 17 }, /* etat  9 */
  254. X  { -1, -1, -1, -1, -1, -1, -1, -1 }  /* etat 10 */
  255. X};
  256. X
  257. X
  258. X
  259. X/* current game
  260. X   the name "tos" means "top of stack"
  261. X   */
  262. Xstatic game * tos = GULL ;
  263. X
  264. X/* array to see the king is in check
  265. X   use in checkroque()
  266. X   */
  267. X
  268. X
  269. X/* booleen d'erreur */
  270. Xint error_flag = FALSE;
  271. X
  272. X
  273. X/* move to display board */
  274. Xstatic int count = 0 ;
  275. X
  276. X
  277. Xstatic int move_to_display[NB_MOVE_TO_DISP] ;
  278. Xstatic int nb_move_to_dsp = 0;
  279. Xstatic int stop_at_display = FALSE;
  280. X
  281. X/* variable holding current move */
  282. Xstatic depl * m = MULL ;
  283. X
  284. X/* current move, used by the parser */
  285. Xstatic int curpiece,  curcol,  curlig ;
  286. Xstatic int curdigit, curmove;
  287. X
  288. Xstatic format * dr;
  289. X
  290. Xstatic int driver; /* driver type, ie gnu, ascii ... */
  291. X
  292. X#define setboard(A,I,J,P,C) ({(A)->board[(I)][(J)] = (P) ; \
  293. X                 (A)->color[(I)][(J)] = (C);})
  294. X#define clsboard(A,I,J,P,C) ({(A)->board[(I)][(J)] = VOID ; \
  295. X                (A)->color[(I)][(J)] = VOID; }))
  296. X
  297. X/* --------------------------- code part --------------------- */
  298. X
  299. X
  300. Xstatic int ispiece(c)
  301. X     char c;
  302. X{
  303. X  register int i;
  304. X  
  305. X  for ( i = 0 ; (i < NUMPIECES) && (c != in_table[i]) ; i++ ) ;
  306. X  /*(void) fprintf(stdout, "piece %d %c\n" , i , c);*/
  307. X  return(i<NUMPIECES);
  308. X}
  309. X
  310. X
  311. Xstatic int piece(c)
  312. X     char c ;
  313. X{
  314. X  register int i;
  315. X  
  316. X  for ( i = 0 ; (i < NUMPIECES) && (c != in_table[i]) ; i++ ) ;
  317. X  if ( i== NUMPIECES)
  318. X    i = PAWN ;
  319. X  return(i);
  320. X}
  321. X
  322. X/* this function return yhe # entry of a keyword in a given table.
  323. X   if key is not present, it returns the default value
  324. X   */
  325. Xstatic int find_keyword(tab, nbentry,defaut,key)
  326. X     char * tab[];
  327. X     int nbentry;
  328. X     int defaut;
  329. X     char *key;
  330. X{
  331. X  int i ;
  332. X
  333. X  for(i=0; (i< nbentry) ;i++)
  334. X    if (strcmp(tab[i],key)==0)
  335. X      return(i);
  336. X
  337. X  /* we failed to find the keyword */
  338. X  (void) fprintf (stderr, "unknow keyword %s in this context\n",key);
  339. X  return(defaut);
  340. X}
  341. X
  342. X/* ---------- board management function ------------- */
  343. X
  344. Xvoid clear_board(g)
  345. X     game *g;
  346. X{
  347. X  register int i,j;
  348. X
  349. X  for (i=0; i < 10; i++ )
  350. X    for (j=0 ; j< 10 ; j++) {
  351. X      g->board[i][j] = VOID;
  352. X      g->color[i][j] = VOID;
  353. X    }
  354. X}
  355. X
  356. Xgame * new_board()
  357. X{
  358. X  game * tmp;
  359. X  int i; 
  360. X
  361. X  tmp = (game *) malloc (sizeof(game));
  362. X  ALLOCP(tmp);
  363. X  /*for (i=0; i < ((sizeof (game))/ sizeof (int)) ; i++)
  364. X    ((int *) tmp)[i] = 0;*/
  365. X  return(tmp);
  366. X}
  367. X
  368. Xvoid init_board(tgm)
  369. X  game * tgm;
  370. X{
  371. X  register int i,j;
  372. X
  373. X  clear_board(tgm);
  374. X
  375. X  for (i=1; i< 9 ; i=i+7) {
  376. X    tgm->board[i][1]= tgm->board[i][8] = ROOK ;
  377. X    tgm->board[i][2]= tgm->board[i][7] = KNIGHT ;
  378. X    tgm->board[i][3]= tgm->board[i][6] = BISHOP ;
  379. X    tgm->board[i][4]= QUEEN;
  380. X    tgm->board[i][5]= KING;
  381. X  }
  382. X  for (i=2; i< 8 ; i=i+5) 
  383. X    for (j=1; j <=8 ; j++)
  384. X      tgm->board[i][j] = PAWN;
  385. X
  386. X  for (i=1; i <=2; i++)
  387. X    for (j=1; j <=8 ; j++) {
  388. X      tgm->color[i][j] = WHITE;
  389. X      tgm->color[i+6][j] = BLACK ;
  390. X    }
  391. X}
  392. X
  393. Xdepl * new_move()
  394. X{
  395. X  depl * tmp;
  396. X  int i; 
  397. X
  398. X  tmp = (depl *) malloc (sizeof(depl));
  399. X  ALLOCP(tmp);
  400. X  /*for (i=0; i < ((sizeof (depl))/ sizeof (int)) ; i++)
  401. X    ((int *) tmp)[i] = 0;*/
  402. X  return(tmp);
  403. X}
  404. X
  405. X
  406. Xvoid init_move(m)
  407. X     depl *m;
  408. X{
  409. X  m->move= 1 ;
  410. X  m->whiteturn = TRUE ;
  411. X}
  412. X     
  413. X/* ----------- semantic evaluation of move ----------- */
  414. X/* check if  position lies within the board
  415. X   */
  416. Xint in_board(l,c)
  417. X     int l,c;
  418. X{
  419. X  return ((c >= 1) && (c <= 8) && (l >= 1) && (l <= 8));
  420. X}
  421. X
  422. X/* check that the path from pos1 to pos2 is free
  423. X   */
  424. Xint path_free(l1, c1, l2, c2)
  425. Xint l1,c1, l2, c2;
  426. X{
  427. X  int li = 1 ;
  428. X  int ci = 1 ;
  429. X  int lig, col;
  430. X
  431. X
  432. X  li = SIGN(l2-l1);
  433. X  ci = SIGN(c2-c1);
  434. X
  435. X
  436. X  if ( c1 == c2 ) {    
  437. X    col = c1;
  438. X    for (lig = l1 +li; lig != l2 ; lig +=li)
  439. X      if (tos->board[lig][col] != VOID)
  440. X    return (FALSE);
  441. X    return(TRUE);
  442. X  }
  443. X
  444. X  if ( l1 == l2) {
  445. X    lig = l1 ;
  446. X    for (col = c1 + ci; col != c2 ; col +=ci)
  447. X      if (tos->board[lig][col] != VOID)
  448. X    return (FALSE);
  449. X    return(TRUE);
  450. X  }
  451. X
  452. X  for (lig = l1+li,col =c1+ci; (lig!=l2) && (col!=c2); lig+=li, col+= ci)
  453. X    if (tos->board[lig][col] != VOID) {
  454. X      return (FALSE);
  455. X    }
  456. X  return(TRUE);
  457. X}
  458. X
  459. X/* check roque is possible */
  460. Xint check_roque()
  461. X{
  462. X  int lig, col ;
  463. X
  464. X  if (m->whiteturn)
  465. X    lig = 1 ;
  466. X  else
  467. X    lig =8;
  468. X  if (m->type == GRANDROQUE)
  469. X    for (col = 2; col < 5 ; col++)
  470. X      if (tos->board[lig][col] != VOID)
  471. X    return(FALSE);
  472. X  if (m->type == PETITROQUE)
  473. X    for (col = 6; col < 7 ; col++)
  474. X      if (tos->board[lig][col] != VOID)
  475. X    return(FALSE);
  476. X  if (m->is_check[CURCOLOR(m)])
  477. X    return(FALSE);
  478. X  return(TRUE);
  479. X}
  480. X  
  481. X/* check -- or guess -- where a given piece come */
  482. Xint guess_piece() {return(tos->board[m->fromlig][m->fromcol]); }
  483. X
  484. X/* try to guess the move -- low-level function */
  485. Xint guess_depl(nb, tab, pl1, pc1, l2,c2,path)
  486. X     int nb;
  487. X     int tab[][2];
  488. X     int *pl1, *pc1;
  489. X     int l2,c2;
  490. X     int path;
  491. X{
  492. X  int i;
  493. X  int c,l;
  494. X
  495. X  for (i=0; i< nb; i++ ) {
  496. X    l = l2 - tab[i][0];
  497. X    c = c2 - tab[i][1];
  498. X    if (in_board(l,c))
  499. X      if ((tos->board[l][c] == m->piece) &&
  500. X      (tos->color[l][c] == CURCOLOR(m)) &&
  501. X      ( !path || (path && path_free(l,c, l2, c2))) &&
  502. X      ( ((*pl1) == 0) || ((*pl1) == l) ) &&
  503. X      ( ((*pc1) == 0) || ((*pc1) == c) ) )
  504. X      {
  505. X    *pl1 = l;
  506. X    *pc1 = c;
  507. X    return(TRUE);
  508. X      }
  509. X  }
  510. X  return(FALSE);
  511. X}
  512. X
  513. X/* check for ambiguitey in a move
  514. X   used in ouptut function: the piece had beenm already moved and
  515. X   if we guess another move, there is an ambiguity
  516. X   */
  517. Xint ambiguity(frompiece, l2, c2)
  518. X     int frompiece, l2, c2 ;
  519. X{
  520. X  int l1 = 0 ;
  521. X  int c1 = 0 ;
  522. X
  523. X  switch(frompiece) {
  524. X  case PAWN:
  525. X    if (m->type == PRISE) {
  526. X      if (m->whiteturn)
  527. X    return(guess_depl(NB_M_PAWN_WX, m_pawn_wx, &l1,&c1, l2,c2, FALSE));
  528. X      else
  529. X    return(guess_depl(NB_M_PAWN_BX, m_pawn_bx, &l1,&c1, l2,c2, FALSE));
  530. X   } else {
  531. X      if (m->whiteturn)
  532. X    return(guess_depl(NB_M_PAWN_MOVE_WD, m_pawn_move_wd, 
  533. X              &l1,&c1, l2,c2, FALSE));
  534. X      else
  535. X    return(guess_depl(NB_M_PAWN_MOVE_BD, m_pawn_move_bd, 
  536. X              &l1,&c1, l2,c2, FALSE));
  537. X    }
  538. X    /* break; */
  539. X  case KNIGHT:
  540. X    return(guess_depl(NB_M_KNIGHT, m_knight, &l1,&c1, l2,c2, FALSE));
  541. X    /* break; */
  542. X  case BISHOP:
  543. X    return(guess_depl(NB_M_BISHOP, m_bishop, &l1,&c1, l2,c2, TRUE));
  544. X    /* break; */
  545. X  case ROOK:
  546. X    return(guess_depl(NB_M_ROOK, m_rook, &l1,&c1, l2,c2, TRUE));
  547. X    /* break; */
  548. X  case QUEEN:
  549. X    return(guess_depl(NB_M_QUEEN, m_queen, &l1,&c1, l2,c2, TRUE));
  550. X    /* break; */
  551. X  case KING:
  552. X    return(guess_depl(NB_M_KING, m_king, &l1,&c1, l2,c2, TRUE));
  553. X    /* break; */
  554. X  default:
  555. X    break;
  556. X  }
  557. X  return(TRUE);
  558. X}
  559. X
  560. Xint check_move(m)
  561. X     depl * m;
  562. X{
  563. X  int l1,c1,l2,c2,l;
  564. X  int tmp; /* tmp boolean */
  565. X  l1 = m->fromlig;
  566. X  c1 = m->fromcol;
  567. X  l2 = m->tolig;
  568. X  c2 = m->tocol;
  569. X
  570. X  if ((m->type == GRANDROQUE) || (m->type == PETITROQUE))
  571. X    return(check_roque());
  572. X
  573. X  if ((tos->board[l1][c1] != m->piece)||
  574. X      (tos->color[l1][c1] != CURCOLOR(m))){
  575. X    printf("==%d\n",tos->board[l1][c1]);
  576. X    error ((stderr,"from position and piece not correct\n"));
  577. X    return(FALSE);
  578. X  }
  579. X
  580. X  /* if prise === FALSE, we must not take a piece */
  581. X  if (tos->board[l2][c2] != VOID 
  582. X      && (m->type != PRISE) && (m->type != PROM_ET_PRISE)) {
  583. X    (void) fprintf(stderr,"catching not indicated at move %d\n",m->move);
  584. X    return(FALSE);
  585. X  }
  586. X
  587. X  /* prendre une de ses propres pieces */
  588. X  if (tos->color[l2][c2] == tos->color[l1][c1] && m->prise) {
  589. X    (void) fprintf(stderr,"attempt to catch same color piece at move %d\n",
  590. X           m->move);
  591. X    return(FALSE);
  592. X  }
  593. X
  594. X  /* we check if the move is a possible one for the piece
  595. X     */
  596. X
  597. X  switch(m->piece) {
  598. X  case PAWN:
  599. X    if (m->prise) {
  600. X      if (m->whiteturn)
  601. X    tmp = guess_depl(NB_M_PAWN_WX, m_pawn_wx, &l1,&c1, l2,c2, FALSE);
  602. X      else
  603. X    tmp = guess_depl(NB_M_PAWN_BX, m_pawn_bx, &l1,&c1, l2,c2, FALSE);
  604. X   } else {
  605. X      if (m->whiteturn)
  606. X    tmp = guess_depl(NB_M_PAWN_WD, m_pawn_wd, &l1,&c1, l2,c2, FALSE);
  607. X      else
  608. X    tmp = guess_depl(NB_M_PAWN_BD, m_pawn_bd, &l1,&c1, l2,c2, FALSE);
  609. X    }
  610. X    /* is it a "prise en passant " */
  611. X    if ((c1 != c2) && (tos->board[l2][c2] == VOID)
  612. X    && (tos->board[l1][c2] == PAWN)) {
  613. X      m->type = EN_PASSANT ;
  614. X      l = l1 + (l2 - l1)/2;
  615. X      /* we must perform here the "en passant" test */
  616. X      tos->board[l1][c2] = VOID ;
  617. X      tos->color[l1][c2] = VOID ;
  618. X      tmp = TRUE;
  619. X    }
  620. X    return(tmp);
  621. X    /* break; */
  622. X  case KNIGHT:
  623. X    return(guess_depl(NB_M_KNIGHT, m_knight, &l1,&c1, l2,c2, FALSE));
  624. X    /* break; */
  625. X  case BISHOP:
  626. X    return(guess_depl(NB_M_BISHOP, m_bishop, &l1,&c1, l2,c2, TRUE));
  627. X    /* break; */
  628. X  case ROOK:
  629. X    return(guess_depl(NB_M_ROOK, m_rook, &l1,&c1, l2,c2, TRUE));
  630. X    /* break; */
  631. X  case QUEEN:
  632. X    return(guess_depl(NB_M_QUEEN, m_queen, &l1,&c1, l2,c2, TRUE));
  633. X    /* break; */
  634. X  case KING:
  635. X    return(guess_depl(NB_M_KING, m_king, &l1,&c1, l2,c2, TRUE));
  636. X    /* break; */
  637. X  default:
  638. X    break;
  639. X  }
  640. X
  641. X  return(TRUE);
  642. X}
  643. X
  644. X/* try to guess the move -- used for shortened notation
  645. X   */
  646. Xint guess_move()
  647. X{
  648. X  int l1,c1,l2,c2;
  649. X
  650. X  if ((m->type == GRANDROQUE) || (m->type == PETITROQUE))
  651. X    return(TRUE);
  652. X
  653. X  l1 = m->fromlig ;
  654. X  c1 = m->fromcol ;
  655. X  l2 = m->tolig;
  656. X  c2 = m->tocol;
  657. X
  658. X  switch(m->piece) {
  659. X  case PAWN:
  660. X    if (m->prise) {
  661. X      if (m->whiteturn)
  662. X    (void) guess_depl(NB_M_PAWN_WX, m_pawn_wx, &l1,&c1, l2,c2, FALSE);
  663. X      else
  664. X    (void) guess_depl(NB_M_PAWN_BX, m_pawn_bx, &l1,&c1, l2,c2, FALSE);
  665. X    } else {
  666. X      if (m->whiteturn)
  667. X    (void) guess_depl(NB_M_PAWN_WD, m_pawn_wd, &l1,&c1, l2,c2, FALSE); 
  668. X      else
  669. X    (void) guess_depl(NB_M_PAWN_BD, m_pawn_bd, &l1,&c1, l2,c2, FALSE); 
  670. X    }
  671. X    break;
  672. X  case KNIGHT:
  673. X    (void) guess_depl(NB_M_KNIGHT, m_knight, &l1,&c1, l2,c2, FALSE);
  674. X    break;
  675. X  case BISHOP:
  676. X    (void) guess_depl(NB_M_BISHOP, m_bishop, &l1,&c1, l2,c2, TRUE);
  677. X    break;
  678. X  case ROOK:
  679. X    (void) guess_depl(NB_M_ROOK, m_rook, &l1,&c1, l2,c2, TRUE);
  680. X    break;
  681. X  case QUEEN:
  682. X    (void) guess_depl(NB_M_QUEEN, m_queen, &l1,&c1, l2,c2, TRUE);
  683. X    break;
  684. X  case KING:
  685. X    (void) guess_depl(NB_M_KING, m_king, &l1,&c1, l2,c2, TRUE);
  686. X    break;
  687. X  default:
  688. X    break;
  689. X  }
  690. X
  691. X  if ((l1 == 0) || (c1 == 0)) {
  692. X    if (m->whiteturn)
  693. X      error((stderr,"unable to guess move %d white (%d)\n",
  694. X         m->move,m->piece));
  695. X    else
  696. X      error((stderr,"unable to guess move %d black (%d)\n",
  697. X         m->move,m->piece));
  698. X    return(FALSE);
  699. X  } else {
  700. X    m->fromcol = c1;
  701. X    m->fromlig = l1;
  702. X    return(TRUE);
  703. X  }
  704. X}
  705. X
  706. X/* --------------- execution of move ----------------- */
  707. X
  708. X/* clear a position */
  709. Xint clear_pos(lig,col)
  710. X     int lig;
  711. X     int col;
  712. X{
  713. X  tos->board[lig][col] = VOID ;
  714. X  tos->color[lig][col] = VOID ;
  715. X  return(TRUE);
  716. X}
  717. X
  718. X/* configure the board */
  719. Xint configure()
  720. X{
  721. X  if (configuring) {
  722. X    if (m->piece == VOID)
  723. X      m->piece = PAWN ;
  724. X    tos->board[m->tolig][m->tocol] = m->piece ;
  725. X    tos->color[m->tolig][m->tocol] = configside ;
  726. X  }
  727. X  return(TRUE);
  728. X}
  729. X
  730. X/* execute a move, no checking */
  731. Xint execute_move()
  732. X{
  733. X  register int i;
  734. X
  735. X  if (m->piece == VOID )
  736. X    m->piece = PAWN;
  737. X
  738. X  if ((m->fromlig == 0) || (m->fromcol == 0))
  739. X    (void) guess_move();
  740. X  
  741. X  /* supply to the -- maybe -- deficiency of input notation
  742. X     */
  743. X  if ((m->fromlig !=0) || (m->fromcol != 0))
  744. X    m->piece = tos->board[m->fromlig][m->fromcol];
  745. X
  746. X  if (tos->board[m->tolig][m->tocol] != VOID) {
  747. X    m->type = PRISE;
  748. X    m->prise = tos->board[m->tolig][m->tocol] ;
  749. X  }
  750. X
  751. X  if (!check_move(m)) {
  752. X    if (m->whiteturn)
  753. X      error((stderr,"white move %d illegal\n",m->move));
  754. X    else
  755. X      error((stderr,"black move %d illegal\n",m->move));
  756. X  }
  757. X
  758. X  if (m->type == PETITROQUE) {
  759. X    if (m->whiteturn)
  760. X      curlig = 1 ;
  761. X    else
  762. X      curlig = 8 ;
  763. X    tos->board[curlig][7] = KING;
  764. X    tos->board[curlig][6] = ROOK;
  765. X    tos->color[curlig][7] = tos->color[curlig][5] ;
  766. X    tos->color[curlig][6] = tos->color[curlig][5] ;
  767. X    (void) clear_pos(curlig, 5);
  768. X    (void) clear_pos(curlig, 8);
  769. X  }
  770. X  if (m->type == GRANDROQUE) {
  771. X    if (m->whiteturn)
  772. X      curlig = 1 ;
  773. X    else
  774. X      curlig = 8 ;
  775. X    tos->board[curlig][3] = KING;
  776. X    tos->board[curlig][4] = ROOK;
  777. X    tos->color[curlig][3] = tos->color[curlig][5] ;
  778. X    tos->color[curlig][4] = tos->color[curlig][5] ;
  779. X    (void) clear_pos(curlig, 5);
  780. X    (void) clear_pos(curlig, 1);
  781. X  }
  782. X
  783. X        
  784. X  if (!(m->type == GRANDROQUE) || (m->type == PETITROQUE)) {
  785. X    if (m->piece == VOID)
  786. X      m->piece = tos->board[m->fromlig][m->fromcol];
  787. X    /*if (m->topiece == VOID)
  788. X      m->topiece = tos->board[m->fromlig][m->fromcol];*/
  789. X    tos->board[m->tolig][m->tocol] = tos->board[m->fromlig][m->fromcol];
  790. X    tos->color[m->tolig][m->tocol] = tos->color[m->fromlig][m->fromcol];
  791. X    (void) clear_pos(m->fromlig,m->fromcol);
  792. X  }
  793. X  
  794. X  if ((m->type == PROMOTION) || (m->type == PROM_ET_PRISE))
  795. X    tos->board[m->tolig][m->tocol] = m->promotion ;
  796. X     
  797. X  output_move(dr,m);
  798. X
  799. X  if (error_flag) {
  800. X    (void) fprintf(dr->outfile, "\nlast position encountered:\n");
  801. X    output_board(dr,tos);
  802. X    close_files();
  803. X    exit(0);
  804. X  }
  805. X
  806. X  /* do we need to display the move ? */
  807. X  if (nb_move_to_dsp > 0) {
  808. X    for (i=0; i < nb_move_to_dsp; i++)
  809. X      if (m->move == (move_to_display[i] ) && !m->whiteturn ) {
  810. X    output_board(dr,tos);
  811. X    if (stop_at_display) {
  812. X      output_end(dr);
  813. X      close_files();
  814. X      exit(0);
  815. X    }
  816. X      }
  817. X  }
  818. X
  819. X  return(TRUE);
  820. X}
  821. X
  822. X/* ------------------ automata ----------------------- */
  823. X
  824. X/* categorise the input for the automata */
  825. Xint typechar(c)
  826. X     char c;
  827. X{
  828. X  if (ispiece(c))
  829. X    return(0);
  830. X  if ((c >=  'a') && ( c <= 'h'))
  831. X    return(1);
  832. X  if ((c >=  '1') && ( c <= '8'))
  833. X    return(2);
  834. X  if ( c== '-' )
  835. X    return(3);
  836. X  if ((c == 'x') || (c == 'X' ))
  837. X    return(4);
  838. X  if (c == '=' )
  839. X    return(5);
  840. X  if (c == '\0' )
  841. X    return(6);
  842. X  return(7);
  843. X}
  844. X
  845. X
  846. X/* execute the actions decided by the automata */
  847. Xint execute(num,c)
  848. X     int num;
  849. X     char c;
  850. X{
  851. X  switch (num) {
  852. X  case 1: /* set cur piece */
  853. X    curpiece = piece(c);
  854. X    break;
  855. X  case 2: /* set cur col */
  856. X    curcol = lettertocol(c);
  857. X    break;
  858. X  case 3: /* set cur lig */
  859. X    curlig = lettertolig(c);
  860. X    break;
  861. X  case 4: /* from = cur ; prise = false */
  862. X    m->piece = curpiece ;
  863. X    m->fromcol = curcol ;
  864. X    m->fromlig = curlig;
  865. X    /*m->topiece = curpiece;*/
  866. X    break;
  867. X  case 5: /* from = cur ; prise = true */
  868. X    m->piece = curpiece ;
  869. X    m->fromcol = curcol ;
  870. X    m->fromlig = curlig;
  871. X    m->type = PRISE ;
  872. X    m->prise = curpiece;
  873. X    break;
  874. X  case 6: /* to = cur ; guess from */
  875. X  case 7: /* to = cur ; guess from ; parse remaining token */
  876. X    m->piece = curpiece ;
  877. X    m->tocol = curcol;
  878. X    m->tolig = curlig ;
  879. X
  880. X    /*m->topiece = curpiece ; /* ? */
  881. X
  882. X    if (configuring)
  883. X      (void) configure();
  884. X    else {
  885. X      (void) execute_move();
  886. X      m->whiteturn = !m->whiteturn ; 
  887. X      if (m->whiteturn) m->move++ ;
  888. X    }
  889. X    break;
  890. X  case 8: /* to = cur */
  891. X  case 9: /* to = cur */
  892. X    m->tocol = curcol;
  893. X    m->tolig = curlig ;
  894. X    /*m->topiece = curpiece ;*/
  895. X
  896. X    if (configuring)
  897. X      (void) configure();
  898. X    else {
  899. X      (void) execute_move();
  900. X      m->whiteturn = !m->whiteturn ; 
  901. X      if (m->whiteturn) m->move++ ;
  902. X    }
  903. X    break;
  904. X  case 10: /* piece = cur piece ; prise = true */
  905. X    /* later : guess from position */
  906. X    m->piece = curpiece ;
  907. X    m->type = PRISE ;
  908. X    break;
  909. X  case 11: /* grand roque */
  910. X  case 12: /* petit roque */
  911. X
  912. X    (void) execute_move();
  913. X
  914. X    m->whiteturn = !m->whiteturn ; 
  915. X    if (m->whiteturn) m->move++ ;
  916. X    break;
  917. X  case 13: /* case of simpliest algebraic notation ;
  918. X          only e2e4 : this is the transition from e2 to e4
  919. X          also the case of move such as Nge2
  920. X          from =cur; prise = FALSE;
  921. X          also:
  922. X          curcol = ...
  923. X          */
  924. X    m->piece = curpiece ;
  925. X    m->fromcol = curcol ;
  926. X    m->fromlig = curlig;
  927. X    /*m->topiece = curpiece;*/
  928. X    m->type = MOVE;
  929. X    curcol = lettertocol(c);
  930. X  case 14: /* promotion, the "=" */
  931. X    break;
  932. X  case 15: /* promotion, the piece name */
  933. X    /* to = cur ; guess from */
  934. X  case 16: 
  935. X    /* to = cur */
  936. X
  937. X    m->tocol = curcol;
  938. X    m->tolig = curlig ;
  939. X    /*m->topiece = curpiece ;*/
  940. X
  941. X    if (m->type == PRISE )
  942. X      m->type = PROM_ET_PRISE ;
  943. X    else
  944. X      m->type = PROMOTION ;
  945. X    m->promotion = curpiece = piece(c) ;
  946. X
  947. X    break;
  948. X  case 17: /* execute move for promotion */
  949. X    (void) execute_move();
  950. X
  951. X    m->whiteturn = !m->whiteturn ; 
  952. X    if (m->whiteturn) m->move++ ;
  953. X    break;
  954. X  case -1:
  955. X    break;
  956. X  default:
  957. X    break;
  958. X  }
  959. X  return(TRUE);
  960. X}
  961. X
  962. Xint parse_number(token)
  963. X     char *token;
  964. X{
  965. X  int curmove = 0 ;
  966. X  int i;
  967. X
  968. X  /* check coherency with internal numbering */
  969. X  i = 0;
  970. X  while (isdigit(token[i])) {
  971. X   curmove = curmove * 10 +  ((int) token[i++] - (int) '0' );
  972. X  }
  973. X  if (curmove != m->move)
  974. X    (void) fprintf(stderr,"problem in move numbering: %d vs %d\n",
  975. X           m->move, curmove);
  976. X  return(TRUE);
  977. X}
  978. X
  979. Xint parse_keyword(token)
  980. X     char *token;
  981. X{
  982. X  char c;
  983. X
  984. X  switch (find_keyword(keywords, NBKEYWORD, KNULL, token)) {
  985. X  case START:
  986. X    configuring = FALSE;
  987. X    m->move = 1;
  988. X    m->whiteturn = TRUE;
  989. X    break;
  990. X  case CLEAR:
  991. X    clear_board(tos);
  992. X    break;
  993. X  case SHOWBOARD:
  994. X    output_board(dr,tos);
  995. X    break;
  996. X  case TOWHITE:
  997. X    m->move = 1;
  998. X    m->whiteturn = TRUE;
  999. X    break;
  1000. X  case TOBLACK:
  1001. X    m->move = 1;
  1002. X    m->whiteturn = FALSE;
  1003. X    break;
  1004. X  case CONFIGWH:
  1005. X    configuring = TRUE ;
  1006. X    configside = WHITE;
  1007. X    break;
  1008. X  case CONFIGBL:
  1009. X    configuring = TRUE ;
  1010. X    configside = BLACK;
  1011. X    break;
  1012. X  case DEFAULTP:
  1013. X    init_board(tos);
  1014. X    break;
  1015. X  case SPECIAL: /* all input, up to \n is copied to output */
  1016. X    while ((( c = getc(infile)) != EOF) && (c != '\n'))
  1017. X      (void) putc (c,dr->outfile);
  1018. X    putc ('\n', dr->outfile);
  1019. X    break;
  1020. X  case KNULL:
  1021. X  default:
  1022. X    break;
  1023. X  }
  1024. X  return(TRUE);
  1025. X}
  1026. X
  1027. Xint parse_roque(token)
  1028. X     char * token;
  1029. X{ 
  1030. X  int i;
  1031. X
  1032. X  for (i=0; i < NBROQUE && (strcmp(c_roque[i],token)!=0); i++) ;
  1033. X  if ( i < NBROQUE ) {
  1034. X    if (strlen(token) == 3) {
  1035. X      m->type = PETITROQUE ;
  1036. X      (void) execute(12,DUMMYCHAR);
  1037. X    } else {
  1038. X      m->type = GRANDROQUE ;
  1039. X      (void) execute(11,DUMMYCHAR);
  1040. X    }
  1041. X    /*(void) fprintf(stderr,"ROQUE\n");*/
  1042. X    return(TRUE);
  1043. X  }
  1044. X
  1045. X  return(FALSE);
  1046. X}
  1047. X
  1048. Xint  parse_move(token)
  1049. X     char *token;
  1050. X{
  1051. X  register int i;
  1052. X  int correcte = FALSE ;
  1053. X  int erreursyntaxe = FALSE ;
  1054. X  int etat =0;
  1055. X  int code;
  1056. X  
  1057. X  i=0;
  1058. X  while ( !correcte && !erreursyntaxe ) {
  1059. X    code = typechar(token[i]);
  1060. X    (void) execute(action[etat][code],token[i]);
  1061. X    etat = transit[etat][code] ;
  1062. X    if (etat == -1) 
  1063. X      erreursyntaxe = TRUE;
  1064. X    if (etat == FINAL)
  1065. X      correcte = TRUE ;
  1066. X    i++;
  1067. X  }
  1068. X  if (erreursyntaxe) {
  1069. X    (void) fprintf(stderr, "no comprende, senor: %s\n",token);
  1070. X    return(FALSE);
  1071. X  }
  1072. X  if (correcte) {
  1073. X    /*(void) fprintf(stderr, "ia panimaiou, davai\n");*/
  1074. X  }
  1075. X  return(TRUE);
  1076. X}
  1077. X
  1078. Xvoid init_parse(m)
  1079. X     depl * m ;
  1080. X{
  1081. X  int i;
  1082. X
  1083. X  /* global position and piece variable initialised to 0
  1084. X     */
  1085. X  /* move and whiteturn unchanged */ 
  1086. X
  1087. X  m->type = MOVE ;
  1088. X
  1089. X  curpiece = m->piece = VOID ;
  1090. X  curcol = m->tocol = m->fromcol = 0;
  1091. X  curlig = m->tolig = m->fromlig = 0;
  1092. X
  1093. X  m->promotion = VOID;
  1094. X  m->prise = VOID;
  1095. X
  1096. X  for (i=0; i< 3; i++)
  1097. X    m->is_check[i] = FALSE ;
  1098. X  curdigit = curmove = 0;
  1099. X}
  1100. X
  1101. X/* ------------------- top routines -------------------- */
  1102. X
  1103. X/* cette fonction analyse les arguments de la ligne de commande
  1104. X   */
  1105. Xint parse_options(argc,argv)
  1106. X     int argc;
  1107. X     char * argv[];
  1108. X{
  1109. X  int narg =1 ;
  1110. X  int i;
  1111. X  register int c;
  1112. X  char cp[132];
  1113. X  char chaine[MAXTOKLEN];
  1114. X
  1115. X  infile = stdin;
  1116. X  dr->outfile = stdout;
  1117. X  nb_move_to_dsp = 0;
  1118. X
  1119. X  while (narg < argc ) {
  1120. X    (void) strcpy (cp,argv[narg]);
  1121. X    switch (cp[0]) {
  1122. X    case '-' :
  1123. X      switch (cp[1]) {
  1124. X      case 'f' : /* from langage */
  1125. X    if  ((narg+1) >= argc )
  1126. X      fatal((stderr,"missing argument to %s option",cp));
  1127. X    narg++ ;
  1128. X    in_language = find_keyword (t_language, NBLANGUAGE,
  1129. X                    DEFAULT_INPUT_LANGUAGE,
  1130. X                    argv[narg]);
  1131. X    break;
  1132. X      case 't' : /* to langage */
  1133. X    if  ((narg+1) >= argc )
  1134. X      fatal((stderr,"missing argument to %s option",cp));
  1135. X    narg++ ;
  1136. X    out_language = find_keyword (t_language, NBLANGUAGE,
  1137. X                     DEFAULT_OUTPUT_LANGUAGE,
  1138. X                     argv[narg]);
  1139. X    break;
  1140. X      case 'o' : /* next arg is output file */
  1141. X    narg++ ;
  1142. X    if ((dr->outfile = fopen (argv[narg],"w+")) == NULL) {
  1143. X      (void) fprintf (stderr,"can't open %s output file\n",argv[narg]);
  1144. X      (void) fprintf (stderr,"assume stdout for output\n");
  1145. X    }
  1146. X    break;
  1147. X      case 'e':
  1148. X    if  ((narg+1) >= argc )
  1149. X      fatal((stderr,"missing argument to %s option",cp));
  1150. X    narg++ ;
  1151. X
  1152. X    i=0;
  1153. X    nb_move_to_dsp = 0;
  1154. X    move_to_display[nb_move_to_dsp] = 0;
  1155. X    while (isdigit(argv[narg][i])) {
  1156. X      move_to_display[nb_move_to_dsp] =
  1157. X        ((int) argv[narg][i] - (int) '0')
  1158. X          + move_to_display[nb_move_to_dsp] * 10;
  1159. X      i++;
  1160. X    }
  1161. X    nb_move_to_dsp++;
  1162. X    stop_at_display = TRUE;
  1163. X    break;
  1164. X      case 'c':
  1165. X    if  ((narg+1) >= argc )
  1166. X      fatal((stderr,"missing argument to %s option",cp));
  1167. X    narg++ ;
  1168. X
  1169. X    i=0;
  1170. X    while (isdigit(argv[narg][i])) {
  1171. X      move_to_display[nb_move_to_dsp] = 0;
  1172. X      while (isdigit(argv[narg][i])) {
  1173. X        move_to_display[nb_move_to_dsp] =
  1174. X          ((int) argv[narg][i] - (int) '0')
  1175. X          + move_to_display[nb_move_to_dsp] * 10;
  1176. X        i++;
  1177. X      }
  1178. X      nb_move_to_dsp++;
  1179. X
  1180. X      if (nb_move_to_dsp > NB_MOVE_TO_DISP)
  1181. X        fatal((stderr,"max. number of move to display exceeded"));
  1182. X
  1183. X      /* process next number */
  1184. X      if (argv[narg][i] == ',')
  1185. X        i++;
  1186. X    }
  1187. X    break;
  1188. X      case 'a': /* algebraic output */
  1189. X    dr->output_move_format = ALGEBRAIC;
  1190. X    break;
  1191. X      case 's':  /* shortened output */
  1192. X    dr->output_move_format = SHORTENED;
  1193. X    break;
  1194. X      case 'b': /* display only the board, no move */
  1195. X    dr->only_board = TRUE;
  1196. X    break;
  1197. X      case 'd': /* output driver */
  1198. X    if  ((narg+1) >= argc )
  1199. X      fatal((stderr,"missing argument to %s option",cp));
  1200. X    narg++ ;
  1201. X    driver = find_keyword(t_output, NB_DRIVER, DEFAULT_DRIVER,
  1202. X                  argv[narg]);
  1203. X    break;
  1204. X      case 'h': /* help file */
  1205. X    (void) strcpy(chaine,LIB_DIR);
  1206. X        if ((fhelp = fopen(strcat(chaine,HELP_FILE),"r")) == NULL)
  1207. X          fatal((stderr,"Can't find help file.\n"));
  1208. X        else {
  1209. X          while ((c = getc(fhelp)) != EOF)
  1210. X            (void) fputc(c,stderr);
  1211. X          (void) fclose(fhelp);
  1212. X      exit(0);
  1213. X        }
  1214. X         break;
  1215. X      default:
  1216. X    error((stderr,"unknown command line options %s\n",cp));
  1217. X    break;
  1218. X      }
  1219. X      break;
  1220. X    default: /* assume this is the input file */
  1221. X      if ((infile = fopen (cp,"r")) == NULL)
  1222. X    fatal((stderr,"can't open %s input file\n",cp));
  1223. X    }
  1224. X    narg++;
  1225. X  } /* process next arg */
  1226. X  return(argc);
  1227. X}
  1228. X
  1229. Xvoid close_files()
  1230. X{
  1231. X  if (infile != stdin )
  1232. X    (void) fclose(infile);
  1233. X  if (dr->outfile != stdout )
  1234. X    (void) fclose(dr->outfile);
  1235. X}
  1236. X
  1237. Xint associe_traduction (table, langage)
  1238. Xchar ** table;
  1239. Xint langage ;
  1240. X{
  1241. X  switch (langage) {
  1242. X  case FRENCH :
  1243. X    *table = c_french ;
  1244. X    break;
  1245. X  case ENGLISH:
  1246. X    *table = c_english ;
  1247. X    break;
  1248. X  case ITALIAN:
  1249. X    *table = c_italian ;
  1250. X    break;
  1251. X  case SPANISH:
  1252. X    *table = c_spanish ;
  1253. X    break;
  1254. X  case GERMAN:
  1255. X    *table = c_german ;
  1256. X    break;
  1257. X  case DUTCH:
  1258. X    *table = c_dutch ;
  1259. X    break;
  1260. X  case RUSSIAN:
  1261. X    (void) fprintf(stderr,"russian not yet implemented\n");
  1262. X    *table = c_russian ;
  1263. X    break;
  1264. X  default:
  1265. X    error((stderr,"unknown langage\n"));
  1266. X  }
  1267. X  return(langage);
  1268. X}
  1269. X
  1270. X/* ------------- main --------------------- */
  1271. X
  1272. Xmain(argc,argv)
  1273. X     int argc;
  1274. X     char * argv[];
  1275. X{
  1276. X  (void) fprintf(stderr,"%s\n",version_string);
  1277. X  
  1278. X  /* allocation of driver descriptor */
  1279. X  dr = new_driver();
  1280. X
  1281. X  /* default configuration */
  1282. X  init_driver(dr,DEFAULT_DRIVER);
  1283. X  (void) associe_traduction(&in_table,  DEFAULT_INPUT_LANGUAGE );
  1284. X  (void) associe_traduction(&(dr->out_table), DEFAULT_OUTPUT_LANGUAGE);
  1285. X
  1286. X  (void) parse_options(argc,argv);
  1287. X
  1288. X  (void) associe_traduction (&in_table, in_language);
  1289. X  (void) associe_traduction (&(dr->out_table), out_language);
  1290. X
  1291. X  /* assoc driver */
  1292. X  init_driver(dr,driver);
  1293. X
  1294. X  configuring = FALSE;
  1295. X  configside = VOID;
  1296. X
  1297. X  /* initialise output file */
  1298. X  output_init(dr);
  1299. X
  1300. X  if (error_flag)
  1301. X    fatal((stderr,"too many errors"));
  1302. X
  1303. X  /* allocation of move descriptor */
  1304. X  m = new_move();
  1305. X  init_move(m);
  1306. X  
  1307. X  /* allocation of board descriptor */
  1308. X  tos = new_board();
  1309. X  init_board(tos);
  1310. X
  1311. X  /*output_board(dr,tos);*/
  1312. X
  1313. X  while (nexttoken()) {
  1314. X    /*(void) fprintf(stdout,"%s%\n", curtok);*/
  1315. X    init_parse(m);
  1316. X    (void) parsetoken();
  1317. X  }
  1318. X  if ((count == 0) && !error_flag)
  1319. X    output_board(dr,tos);
  1320. X
  1321. X  if (error_flag) {
  1322. X    error((stderr,"last valid position:\n"));
  1323. X    output_board(dr,tos);
  1324. X    fatal((stderr,"too many errors"));
  1325. X  }
  1326. X
  1327. X  /* terminates output files */
  1328. X  output_end(dr);
  1329. X
  1330. X  /* close files */
  1331. X  close_files();
  1332. X
  1333. X  /* exit properly */
  1334. X#ifdef TURBOC
  1335. X  return(TRUE);
  1336. X#else
  1337. X  exit(0);
  1338. X#endif
  1339. X}
  1340. END_OF_FILE
  1341. if test 31006 -ne `wc -c <'notation.c'`; then
  1342.     echo shar: \"'notation.c'\" unpacked with wrong size!
  1343. fi
  1344. # end of 'notation.c'
  1345. fi
  1346. echo shar: End of archive 3 \(of 3\).
  1347. cp /dev/null ark3isdone
  1348. MISSING=""
  1349. for I in 1 2 3 ; do
  1350.     if test ! -f ark${I}isdone ; then
  1351.     MISSING="${MISSING} ${I}"
  1352.     fi
  1353. done
  1354. if test "${MISSING}" = "" ; then
  1355.     echo You have unpacked all 3 archives.
  1356.     rm -f ark[1-9]isdone
  1357. else
  1358.     echo You still need to unpack the following archives:
  1359.     echo "        " ${MISSING}
  1360. fi
  1361. ##  End of shell archive.
  1362. exit 0
  1363.  
  1364. --
  1365. Henry Thomas - IRISA          - E-mail: Henry.Thomas@irisa.fr 
  1366. Campus Universitaire de Beaulieu - Phone: (+33)99 36 20 00 +549  
  1367. 35042 RENNES CEDEX FRANCE      - Fax: (+33)99 38 38 32 Telex: UNIRISA 950473F
  1368. Telex Atlas X400: /X121=842950473/@atlas.fr, Fax:/X121=200099383832/@atlas.fr
  1369. --
  1370. ... Words, and the words of men, flicker and flutter and beat
  1371. Warning, sorrow and gain, salutations and mirth...        R. Kipling
  1372.  
  1373. exit 0 # Just in case...
  1374. -- 
  1375. Kent Landfield                   INTERNET: kent@sparky.IMD.Sterling.COM
  1376. Sterling Software, IMD           UUCP:     uunet!sparky!kent
  1377. Phone:    (402) 291-8300         FAX:      (402) 291-4362
  1378. Please send comp.sources.misc-related mail to kent@uunet.uu.net.
  1379.